<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<!-- 
	Copyright (C) 2007, 2008, 2009, 2010, 2011. PARP Research Group.
	<http://perception.inf.um.es>
	University of Murcia, Spain.

	This file is part of the QVision library.

	QVision is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, version 3 of the License.

	QVision is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with QVision. If not, see <http://www.gnu.org/licenses/>.
-->

<html><head><meta http-equiv="content-Type" content="text/html;charset=UTF-8">
<title>QVision: Qt&#39;s Image, Video and Computer Vision Library</title>
<meta name="title" content="QVision" />
<meta name="dc.title" content="QVision" />
<meta name="url" content="http://perception.inf.um.es/QVision" />
<meta name="author" content="PARP Research Group - http://perception.inf.um.es" />
<meta name="revisit-after" content="30 DAYS"/>
<meta name="robots" content="index,follow"/>
<meta name="classification" content="*">
<meta name="rating" content="Safe For Kids">
<meta name="distribution" content="GLOBAL"/>
<meta name="description" content="Qt's Image, Video and Computer Vision Library"/>
<meta name="page-topic" content="Computer Vision research and prototype programming"/>
<meta name="geo.country" content="ES" />

<!--
Keywords:
By license:		open source, gnu, lgpl, gpl, free
By theme:		computer vision, image processing, robotics, programming, source, development
By usage:		library, toolkit, framework, prototype, application
By programming specs:	object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping
Interoperability with:	Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack
Functionallity:		image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface
Main data-types:	matrix, vector, tensor, quaternion, image, polyline
Video sources:		webcam, camera, stream
Devices:		embedded, desktop computer, laptop, mini-laptop
Authors:		PARP research group. University of Murcia, Spain.
-->

<meta name="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="title" content="QVision"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="tabs.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="favicon.ico" />
</head><body>

<table width="100%"><tr>
	<td><a href="http://perception.inf.um.es/"><img src="parp.png" border="0" /> <big>PARP Research Group</big></a></td>
	<td align="right"><a href="http://www.um.es/"><big>Universidad de Murcia</big> <img src="um.png" border="0" /></a></td>
</tr></table>

<hr /><br />

<table width="95%" align="center"><tr><td>

<!-- Generated by Doxygen 1.6.3 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
          <form id="FSearchBox" action="search.php" method="get">
            <img id="MSearchSelect" src="search/search.png" alt=""/>
            <input type="text" id="MSearchField" name="query" value="Search" size="20" accesskey="S" 
                   onfocus="searchBox.OnSearchFieldFocus(true)" 
                   onblur="searchBox.OnSearchFieldFocus(false)"/>
          </form>
        </div>
      </li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>File&nbsp;Members</span></a></li>
    </ul>
  </div>
<h1>src/qvblockprogramming/qvguiblocks/qvdesigner/slate/node.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> *      Copyright (C) 2008, 2009, 2010, 2011, 2012. PARP Research Group.</span>
<a name="l00003"></a>00003 <span class="comment"> *      &lt;http://perception.inf.um.es&gt;</span>
<a name="l00004"></a>00004 <span class="comment"> *      University of Murcia, Spain.</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> *      This file is part of the QVision library.</span>
<a name="l00007"></a>00007 <span class="comment"> *</span>
<a name="l00008"></a>00008 <span class="comment"> *      QVision is free software: you can redistribute it and/or modify</span>
<a name="l00009"></a>00009 <span class="comment"> *      it under the terms of the GNU Lesser General Public License as</span>
<a name="l00010"></a>00010 <span class="comment"> *      published by the Free Software Foundation, version 3 of the License.</span>
<a name="l00011"></a>00011 <span class="comment"> *</span>
<a name="l00012"></a>00012 <span class="comment"> *      QVision is distributed in the hope that it will be useful,</span>
<a name="l00013"></a>00013 <span class="comment"> *      but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00014"></a>00014 <span class="comment"> *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<a name="l00015"></a>00015 <span class="comment"> *      GNU Lesser General Public License for more details.</span>
<a name="l00016"></a>00016 <span class="comment"> *</span>
<a name="l00017"></a>00017 <span class="comment"> *      You should have received a copy of the GNU Lesser General Public</span>
<a name="l00018"></a>00018 <span class="comment"> *      License along with QVision. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<a name="l00019"></a>00019 <span class="comment"> */</span>
<a name="l00020"></a>00020 
<a name="l00021"></a>00021 <span class="preprocessor">#include &lt;QtGui&gt;</span>
<a name="l00022"></a>00022 
<a name="l00023"></a>00023 <span class="preprocessor">#include &quot;node.h&quot;</span>
<a name="l00024"></a>00024 <span class="preprocessor">#include &lt;QGraphicsScene&gt;</span>
<a name="l00025"></a>00025 
<a name="l00026"></a>00026 
<a name="l00027"></a>00027 Node::Node(QString _name, SlateWindow *wind, QGraphicsItem * parent, QGraphicsScene * scene): QGraphicsItem(parent, scene), name(), type(),
<a name="l00028"></a>00028         itemProp(<span class="stringliteral">&quot;Group&quot;</span>), numProp(itemProp.getProperties().size()), window(wind), clickedPoint(-1), externalMarkedPoint(-1), markedPoint(-1)
<a name="l00029"></a>00029 {
<a name="l00030"></a>00030     myTextColor = Qt::darkGreen;
<a name="l00031"></a>00031     myOutlineColor = Qt::darkBlue;
<a name="l00032"></a>00032     myBackgroundColor = Qt::white;
<a name="l00033"></a>00033     setFlags(ItemIsMovable | ItemIsSelectable);
<a name="l00034"></a>00034 
<a name="l00035"></a>00035         type = <span class="stringliteral">&quot;Group&quot;</span>;
<a name="l00036"></a>00036         name = _name;
<a name="l00037"></a>00037         <span class="keywordtype">id</span> = 0;
<a name="l00038"></a>00038 
<a name="l00039"></a>00039         CorrectTextChange();
<a name="l00040"></a>00040         update();
<a name="l00041"></a>00041 }
<a name="l00042"></a>00042 
<a name="l00043"></a>00043 Node::Node(ItemProperties item, QString _name, uint _id, SlateWindow *wind, QGraphicsItem * parent, QGraphicsScene * scene): QGraphicsItem(parent, scene), name(),
<a name="l00044"></a>00044         type(), itemProp(item), numProp(itemProp.getProperties().size()), window(wind), clickedPoint(-1), externalMarkedPoint(-1), markedPoint(-1)
<a name="l00045"></a>00045 {
<a name="l00046"></a>00046     myTextColor = Qt::darkGreen;
<a name="l00047"></a>00047     myOutlineColor = Qt::darkBlue;
<a name="l00048"></a>00048     myBackgroundColor = Qt::white;
<a name="l00049"></a>00049     setFlags(ItemIsMovable | ItemIsSelectable);
<a name="l00050"></a>00050 
<a name="l00051"></a>00051         type = itemProp.getType();
<a name="l00052"></a>00052         name = _name;
<a name="l00053"></a>00053         <span class="keywordtype">id</span> = _id;
<a name="l00054"></a>00054 
<a name="l00055"></a>00055         CorrectTextChange();
<a name="l00056"></a>00056         update();
<a name="l00057"></a>00057 }
<a name="l00058"></a>00058 
<a name="l00059"></a>00059 Node::~Node()
<a name="l00060"></a>00060 {
<a name="l00061"></a>00061      <span class="keywordflow">foreach</span> (Link *link, getLinks())
<a name="l00062"></a>00062         <span class="keyword">delete</span> link;
<a name="l00063"></a>00063 }
<a name="l00064"></a>00064 
<a name="l00065"></a>00065 <span class="keywordtype">void</span> Node::addInLink(Link *link)
<a name="l00066"></a>00066 {
<a name="l00067"></a>00067     myInLinks.append(link);
<a name="l00068"></a>00068 }
<a name="l00069"></a>00069 
<a name="l00070"></a>00070 <span class="keywordtype">void</span> Node::addOutLink(Link *link)
<a name="l00071"></a>00071 {
<a name="l00072"></a>00072     myOutLinks.append(link);
<a name="l00073"></a>00073 }
<a name="l00074"></a>00074 
<a name="l00075"></a>00075 <span class="keywordtype">void</span> Node::removeLink(Link *link)
<a name="l00076"></a>00076 {
<a name="l00077"></a>00077     myInLinks.removeAll(link);
<a name="l00078"></a>00078         myOutLinks.removeAll(link);
<a name="l00079"></a>00079 }
<a name="l00080"></a>00080 
<a name="l00081"></a>00081 QList&lt;Link *&gt; Node::getLinks()<span class="keyword"> const</span>
<a name="l00082"></a>00082 <span class="keyword"></span>{
<a name="l00083"></a>00083         <span class="keywordflow">return</span> (myInLinks + myOutLinks);
<a name="l00084"></a>00084 }
<a name="l00085"></a>00085 
<a name="l00086"></a>00086 QList&lt;Link *&gt; Node::getInLinks()<span class="keyword"> const</span>
<a name="l00087"></a>00087 <span class="keyword"></span>{
<a name="l00088"></a>00088         <span class="keywordflow">return</span> myInLinks;
<a name="l00089"></a>00089 }
<a name="l00090"></a>00090 
<a name="l00091"></a>00091 QList&lt;Link *&gt; Node::getOutLinks()<span class="keyword"> const</span>
<a name="l00092"></a>00092 <span class="keyword"></span>{
<a name="l00093"></a>00093         <span class="keywordflow">return</span> myOutLinks;
<a name="l00094"></a>00094 }
<a name="l00095"></a>00095 
<a name="l00096"></a>00096 <span class="keywordtype">int</span> Node::precursors(QList&lt;Node *&gt; tail)
<a name="l00097"></a>00097 {
<a name="l00098"></a>00098         <span class="keywordflow">if</span> (myInLinks.isEmpty()) {
<a name="l00099"></a>00099                 <span class="keywordflow">return</span> 0;
<a name="l00100"></a>00100         }
<a name="l00101"></a>00101         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (tail.contains(<span class="keyword">this</span>)) { <span class="comment">// si se ha producido un ciclo</span>
<a name="l00102"></a>00102                 <span class="keywordflow">return</span> 0;
<a name="l00103"></a>00103         }
<a name="l00104"></a>00104         <span class="keywordflow">else</span> {
<a name="l00105"></a>00105                 <span class="keywordtype">int</span> maxPre = 0;
<a name="l00106"></a>00106                 tail.append(<span class="keyword">this</span>);
<a name="l00107"></a>00107                 <span class="keywordflow">foreach</span>(Link *link, myInLinks) {
<a name="l00108"></a>00108                         <span class="keywordflow">if</span> ((link) &amp;&amp; (link-&gt;fromNode())) {
<a name="l00109"></a>00109                                 <span class="keywordtype">int</span> pre = link-&gt;fromNode()-&gt;precursors(tail);
<a name="l00110"></a>00110                                 <span class="keywordflow">if</span> (maxPre &lt; pre) maxPre = pre; <span class="comment">//actualizo maxPre</span>
<a name="l00111"></a>00111                         }
<a name="l00112"></a>00112                 }
<a name="l00113"></a>00113                 <span class="keywordflow">return</span> maxPre + 1;
<a name="l00114"></a>00114         }
<a name="l00115"></a>00115 }
<a name="l00116"></a>00116 
<a name="l00117"></a>00117 
<a name="l00118"></a>00118 
<a name="l00119"></a>00119 <span class="keywordtype">void</span> Node::setText(<span class="keyword">const</span> QString &amp;text)
<a name="l00120"></a>00120 {
<a name="l00121"></a>00121     prepareGeometryChange();
<a name="l00122"></a>00122     myText = text;
<a name="l00123"></a>00123     update();
<a name="l00124"></a>00124 }
<a name="l00125"></a>00125 
<a name="l00126"></a>00126 QString Node::text()<span class="keyword"> const</span>
<a name="l00127"></a>00127 <span class="keyword"></span>{
<a name="l00128"></a>00128     <span class="keywordflow">return</span> myText;
<a name="l00129"></a>00129 }
<a name="l00130"></a>00130 
<a name="l00131"></a>00131 <span class="keywordtype">void</span> Node::setTextColor(<span class="keyword">const</span> QColor &amp;color)
<a name="l00132"></a>00132 {
<a name="l00133"></a>00133     myTextColor = color;
<a name="l00134"></a>00134     update();
<a name="l00135"></a>00135 }
<a name="l00136"></a>00136 
<a name="l00137"></a>00137 QColor Node::textColor()<span class="keyword"> const</span>
<a name="l00138"></a>00138 <span class="keyword"></span>{
<a name="l00139"></a>00139     <span class="keywordflow">return</span> myTextColor;
<a name="l00140"></a>00140 }
<a name="l00141"></a>00141 
<a name="l00142"></a>00142 <span class="keywordtype">void</span> Node::setOutlineColor(<span class="keyword">const</span> QColor &amp;color)
<a name="l00143"></a>00143 {
<a name="l00144"></a>00144     myOutlineColor = color;
<a name="l00145"></a>00145     update();
<a name="l00146"></a>00146 }
<a name="l00147"></a>00147 
<a name="l00148"></a>00148 QColor Node::outlineColor()<span class="keyword"> const</span>
<a name="l00149"></a>00149 <span class="keyword"></span>{
<a name="l00150"></a>00150     <span class="keywordflow">return</span> myOutlineColor;
<a name="l00151"></a>00151 }
<a name="l00152"></a>00152 
<a name="l00153"></a>00153 <span class="keywordtype">void</span> Node::setBackgroundColor(<span class="keyword">const</span> QColor &amp;color)
<a name="l00154"></a>00154 {
<a name="l00155"></a>00155     myBackgroundColor = color;
<a name="l00156"></a>00156     update();
<a name="l00157"></a>00157 }
<a name="l00158"></a>00158 
<a name="l00159"></a>00159 QColor Node::backgroundColor()<span class="keyword"> const</span>
<a name="l00160"></a>00160 <span class="keyword"></span>{
<a name="l00161"></a>00161     <span class="keywordflow">return</span> myBackgroundColor;
<a name="l00162"></a>00162 }
<a name="l00163"></a>00163 
<a name="l00164"></a>00164 QRectF Node::boundingRect()<span class="keyword"> const</span>
<a name="l00165"></a>00165 <span class="keyword"></span>{
<a name="l00166"></a>00166     <span class="keyword">const</span> <span class="keywordtype">int</span> Margin = 1;
<a name="l00167"></a>00167     <span class="keywordflow">return</span> outlineRect().adjusted(-Margin, -Margin, +Margin, +Margin);
<a name="l00168"></a>00168 }
<a name="l00169"></a>00169 
<a name="l00170"></a>00170 QPainterPath Node::shape()<span class="keyword"> const</span>
<a name="l00171"></a>00171 <span class="keyword"></span>{
<a name="l00172"></a>00172     QRectF rect = outlineRect();
<a name="l00173"></a>00173 
<a name="l00174"></a>00174     QPainterPath path;
<a name="l00175"></a>00175     path.addRoundRect(rect, roundness(rect.width()),
<a name="l00176"></a>00176                       roundness(rect.height()));
<a name="l00177"></a>00177     <span class="keywordflow">return</span> path;
<a name="l00178"></a>00178 }
<a name="l00179"></a>00179 
<a name="l00180"></a>00180 uint Node::getId()
<a name="l00181"></a>00181 {
<a name="l00182"></a>00182         <span class="keywordflow">return</span> id;
<a name="l00183"></a>00183 }
<a name="l00184"></a>00184 
<a name="l00185"></a>00185 <span class="keywordtype">void</span> Node::paint(QPainter *painter, <span class="keyword">const</span> QStyleOptionGraphicsItem *option, QWidget * <span class="comment">/* widget */</span>)
<a name="l00186"></a>00186 {
<a name="l00187"></a>00187     QPen pen(myOutlineColor);
<a name="l00188"></a>00188     <span class="keywordflow">if</span> (option-&gt;state &amp; QStyle::State_Selected) {
<a name="l00189"></a>00189         pen.setStyle(Qt::DotLine);
<a name="l00190"></a>00190         pen.setWidth(2);
<a name="l00191"></a>00191     }
<a name="l00192"></a>00192     painter-&gt;setPen(pen);
<a name="l00193"></a>00193     painter-&gt;setBrush(myBackgroundColor);
<a name="l00194"></a>00194 
<a name="l00195"></a>00195     QRectF rect = outlineRect();
<a name="l00196"></a>00196         painter-&gt;drawRect(rect);
<a name="l00197"></a>00197         painter-&gt;drawLine((<span class="keywordtype">int</span>)rect.left(), (int)(rect.top() + lineSpacing), (<span class="keywordtype">int</span>)rect.right(), (int)(rect.top() + lineSpacing));
<a name="l00198"></a>00198 
<a name="l00199"></a>00199     painter-&gt;setPen(myTextColor);
<a name="l00200"></a>00200         <span class="comment">//painter-&gt;drawText(rect, Qt::AlignTop | Qt::AlignHCenter, QString(&quot;&quot;) + QString(&quot;(%1) &quot;).arg(getId()) + name);</span>
<a name="l00201"></a>00201     painter-&gt;drawText(rect, Qt::AlignTop | Qt::AlignHCenter, QString(<span class="stringliteral">&quot;&quot;</span>) + name);
<a name="l00202"></a>00202     painter-&gt;drawText(rect.adjusted(0.0, lineSpacing, 0.0, 0.0), Qt::AlignTop | Qt::AlignHCenter, myText);
<a name="l00203"></a>00203 
<a name="l00204"></a>00204         <span class="comment">// y pinta los puntos de unión a ambos lados del texto</span>
<a name="l00205"></a>00205     painter-&gt;setPen(Qt::white);
<a name="l00206"></a>00206         painter-&gt;setBrush(Qt::black);
<a name="l00207"></a>00207         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; numProp; i++)
<a name="l00208"></a>00208         {
<a name="l00209"></a>00209                 <span class="keywordflow">if</span> (itemProp.isInput(i)) <span class="comment">// si tiene enlace de entrada lo pinto</span>
<a name="l00210"></a>00210                         painter-&gt;drawEllipse((<span class="keywordtype">int</span>)(rect.left() + lineSpacing*0.1), (int)(rect.top() + lineSpacing*(i + 1.1)), (<span class="keywordtype">int</span>)(lineSpacing*0.8), (int)(lineSpacing*0.8));
<a name="l00211"></a>00211                 <span class="keywordflow">if</span> (itemProp.isOutput(i)) <span class="comment">// // si tiene enlace de salida lo pinto</span>
<a name="l00212"></a>00212                         painter-&gt;drawEllipse((<span class="keywordtype">int</span>)(rect.right() - lineSpacing*0.9), (int)(rect.top() + lineSpacing*(i + 1.1)), (<span class="keywordtype">int</span>)(lineSpacing*0.8), (int)(lineSpacing*0.8));
<a name="l00213"></a>00213         }
<a name="l00214"></a>00214 
<a name="l00215"></a>00215         <span class="comment">// si uno de los puntos está marcado, lo pinta dependiendo de su validez</span>
<a name="l00216"></a>00216         <span class="keywordflow">if</span> (markedPoint &gt;= 0)
<a name="l00217"></a>00217         {
<a name="l00218"></a>00218                 <span class="keywordflow">if</span> (markedValidity) painter-&gt;setBrush(Qt::green);
<a name="l00219"></a>00219                 <span class="keywordflow">else</span>                            painter-&gt;setBrush(Qt::red);
<a name="l00220"></a>00220 
<a name="l00221"></a>00221                 <span class="keywordflow">if</span> (markedPoint &lt; numProp)
<a name="l00222"></a>00222                         painter-&gt;drawEllipse((<span class="keywordtype">int</span>)(rect.left() + lineSpacing*0.1), (int)(rect.top() + lineSpacing*(markedPoint + 1.1)), (<span class="keywordtype">int</span>)(lineSpacing*0.8), (int)(lineSpacing*0.8));
<a name="l00223"></a>00223                 <span class="keywordflow">else</span>
<a name="l00224"></a>00224                         painter-&gt;drawEllipse((<span class="keywordtype">int</span>)(rect.right() - lineSpacing*0.9), (int)(rect.top() + lineSpacing*(markedPoint - numProp + 1.1)), (<span class="keywordtype">int</span>)(lineSpacing*0.8), (int)(lineSpacing*0.8));
<a name="l00225"></a>00225         }
<a name="l00226"></a>00226 }
<a name="l00227"></a>00227 
<a name="l00228"></a>00228 <span class="comment">// devuelve la posición (en cordenadas de la scena) del centro del punto indicado por el índice point, si se sale del rango devuelve la posición del nodo</span>
<a name="l00229"></a>00229 QPointF Node::scenePointPos(<span class="keywordtype">int</span> point)<span class="keyword"> const</span>
<a name="l00230"></a>00230 <span class="keyword"></span>{
<a name="l00231"></a>00231         QRectF rect = outlineRect();
<a name="l00232"></a>00232 
<a name="l00233"></a>00233         <span class="keywordflow">if</span> (point &lt; 0) <span class="keywordflow">return</span> this-&gt;scenePos();
<a name="l00234"></a>00234         <span class="keywordflow">if</span> (point &lt; numProp) <span class="keywordflow">return</span> mapToScene( QPointF(rect.left() + lineSpacing*0.1, rect.top() + lineSpacing*(point + 1.5)) );
<a name="l00235"></a>00235         <span class="keywordflow">if</span> (point &lt; 2 * numProp) <span class="keywordflow">return</span> mapToScene( QPointF(rect.right() - lineSpacing*0.2, rect.top() + lineSpacing*(point-numProp + 1.5)) );
<a name="l00236"></a>00236         <span class="keywordflow">return</span> this-&gt;scenePos();
<a name="l00237"></a>00237 }
<a name="l00238"></a>00238 
<a name="l00239"></a>00239 QPointF Node::scenePointPos(QString name, <span class="keywordtype">bool</span> in)<span class="keyword"> const</span>
<a name="l00240"></a>00240 <span class="keyword"></span>{
<a name="l00241"></a>00241         <span class="keywordflow">return</span> scenePointPos(propPoint(name, in));
<a name="l00242"></a>00242 }
<a name="l00243"></a>00243 
<a name="l00244"></a>00244 
<a name="l00245"></a>00245 <span class="keywordtype">int</span> Node::numProps()<span class="keyword"> const</span>
<a name="l00246"></a>00246 <span class="keyword"></span>{
<a name="l00247"></a>00247         <span class="keywordflow">return</span> numProp;
<a name="l00248"></a>00248 }
<a name="l00249"></a>00249 
<a name="l00250"></a>00250 
<a name="l00251"></a>00251 <span class="keywordtype">void</span> Node::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
<a name="l00252"></a>00252 {
<a name="l00253"></a>00253     QRectF rect = outlineRect();
<a name="l00254"></a>00254         QPointF click = mapFromScene(event-&gt;scenePos());
<a name="l00255"></a>00255 
<a name="l00256"></a>00256         <span class="keywordflow">if</span> (click.y() &gt; rect.top() + lineSpacing) {
<a name="l00257"></a>00257                 window-&gt;showProperties(<span class="keyword">this</span>);
<a name="l00258"></a>00258         }
<a name="l00259"></a>00259         <span class="keywordflow">else</span> {
<a name="l00260"></a>00260                 QString text = QInputDialog::getText(event-&gt;widget(),
<a name="l00261"></a>00261                                                         tr(<span class="stringliteral">&quot;Edit Name&quot;</span>), tr(<span class="stringliteral">&quot;Enter new name:&quot;</span>),
<a name="l00262"></a>00262                                                         QLineEdit::Normal, name);
<a name="l00263"></a>00263                 <span class="keywordflow">if</span> (!text.isEmpty()) {
<a name="l00264"></a>00264                         window-&gt;setName(<span class="keyword">this</span>, text);
<a name="l00265"></a>00265                 }
<a name="l00266"></a>00266         }
<a name="l00267"></a>00267 }
<a name="l00268"></a>00268 
<a name="l00269"></a>00269 <span class="keywordtype">void</span> Node::setName(QString _name) {
<a name="l00270"></a>00270         prepareGeometryChange();
<a name="l00271"></a>00271         name = _name;
<a name="l00272"></a>00272         CorrectTextChange();
<a name="l00273"></a>00273         update();
<a name="l00274"></a>00274 }
<a name="l00275"></a>00275 
<a name="l00276"></a>00276 <span class="comment">// estas funciones son para conseguir que los puntos se pinten de rojo cunado se pasa sobre ellos</span>
<a name="l00277"></a>00277 <span class="comment">// y que se cree la linea al arrastar y creen los link cuando suelte en una posición correcta</span>
<a name="l00278"></a>00278 <span class="keywordtype">void</span> Node::mousePressEvent(QGraphicsSceneMouseEvent * event)
<a name="l00279"></a>00279 {
<a name="l00280"></a>00280         <span class="keywordflow">if</span> (!window-&gt;isSelected(<span class="keyword">this</span>)) {
<a name="l00281"></a>00281                 window-&gt;clearSelection();
<a name="l00282"></a>00282                 setSelected(<span class="keyword">true</span>);
<a name="l00283"></a>00283         }
<a name="l00284"></a>00284 
<a name="l00285"></a>00285         clickedPoint = pointAt(event-&gt;pos());
<a name="l00286"></a>00286         <span class="keywordflow">if</span> (clickedPoint &lt; 0)
<a name="l00287"></a>00287         {
<a name="l00288"></a>00288                 <span class="comment">// si no coincidía con un punto mueve el item normalmente</span>
<a name="l00289"></a>00289                 QGraphicsItem::mousePressEvent(event);
<a name="l00290"></a>00290         }
<a name="l00291"></a>00291         <span class="keywordflow">else</span>
<a name="l00292"></a>00292         {
<a name="l00293"></a>00293                 <span class="comment">// si coincide con un punto crea una línea indicadora del posible enlace</span>
<a name="l00294"></a>00294                 line = <span class="keyword">new</span> QGraphicsLineItem( QLineF(event-&gt;scenePos(), <span class="keyword">event</span>-&gt;scenePos()) );
<a name="l00295"></a>00295                 line-&gt;setZValue(1000);
<a name="l00296"></a>00296                 scene()-&gt;addItem(line);
<a name="l00297"></a>00297         }
<a name="l00298"></a>00298 }
<a name="l00299"></a>00299 
<a name="l00300"></a>00300 <span class="keywordtype">void</span> Node::prepareHierarchy()
<a name="l00301"></a>00301 {
<a name="l00302"></a>00302         <span class="comment">// actualiza a toda la gerarquía de grupos que tiene por encima</span>
<a name="l00303"></a>00303         QGraphicsItem *ancestor = parentItem();
<a name="l00304"></a>00304         <span class="keywordflow">while</span> (ancestor) {
<a name="l00305"></a>00305                 <span class="keywordflow">if</span> (dynamic_cast&lt;Node *&gt;(ancestor))
<a name="l00306"></a>00306                         ((Node *)ancestor)-&gt;publicPrepareGeometryChange();
<a name="l00307"></a>00307                 ancestor = ancestor-&gt;parentItem();
<a name="l00308"></a>00308         }
<a name="l00309"></a>00309 }
<a name="l00310"></a>00310 
<a name="l00311"></a>00311 <span class="keywordtype">void</span> Node::publicPrepareGeometryChange() {
<a name="l00312"></a>00312         prepareGeometryChange();
<a name="l00313"></a>00313 }
<a name="l00314"></a>00314 
<a name="l00315"></a>00315 <span class="keywordtype">void</span> Node::updateHierarchy()
<a name="l00316"></a>00316 {
<a name="l00317"></a>00317         <span class="comment">// actualiza a toda la gerarquía de grupos que tiene por encima</span>
<a name="l00318"></a>00318         QGraphicsItem *ancestor = parentItem();
<a name="l00319"></a>00319         <span class="keywordflow">while</span> (ancestor) {
<a name="l00320"></a>00320                 ancestor-&gt;update();
<a name="l00321"></a>00321                 <span class="keywordflow">if</span> (dynamic_cast&lt;Node *&gt;(ancestor))
<a name="l00322"></a>00322                         ((Node *)ancestor)-&gt;updateLinksPos();
<a name="l00323"></a>00323                 ancestor = ancestor-&gt;parentItem();
<a name="l00324"></a>00324         }
<a name="l00325"></a>00325 }
<a name="l00326"></a>00326 
<a name="l00327"></a>00327 <span class="keywordtype">void</span> Node::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
<a name="l00328"></a>00328 {
<a name="l00329"></a>00329         <span class="comment">// si no se ha pinchado sobre un punto, muevo el item</span>
<a name="l00330"></a>00330         <span class="keywordflow">if</span> (clickedPoint &lt; 0)
<a name="l00331"></a>00331         {
<a name="l00332"></a>00332                 <span class="comment">// actualiza a toda la gerarquía de grupos que tiene por encima, por si han de encogerse</span>
<a name="l00333"></a>00333                 updateHierarchy();
<a name="l00334"></a>00334 
<a name="l00335"></a>00335                 QGraphicsItem::mouseMoveEvent(event);
<a name="l00336"></a>00336 
<a name="l00337"></a>00337                 <span class="comment">// actualiza a toda la gerarquía de grupos que tiene por encima, por si han de ensancharse</span>
<a name="l00338"></a>00338                 updateHierarchy();
<a name="l00339"></a>00339         }
<a name="l00340"></a>00340         <span class="keywordflow">else</span>
<a name="l00341"></a>00341         {
<a name="l00342"></a>00342                 <span class="comment">// desplazo la línea como el mouse, pero un poco (0.5) más corta, ya que sino cuando busquemos el item de justo</span>
<a name="l00343"></a>00343                 <span class="comment">// debajo del cursor nos puede dar la própia línea en vez del que buscamos.</span>
<a name="l00344"></a>00344                 QLineF shortLine = QLineF(line-&gt;line().p1(), <span class="keyword">event</span>-&gt;scenePos());
<a name="l00345"></a>00345                 shortLine.setLength(shortLine.length() - 0.5);
<a name="l00346"></a>00346                 line-&gt;setLine(shortLine);
<a name="l00347"></a>00347 
<a name="l00348"></a>00348                 <span class="comment">// si había un punto marcado lo desmarco</span>
<a name="l00349"></a>00349                 <span class="keywordflow">if</span> (externalMarkedPoint &gt;= 0)
<a name="l00350"></a>00350                 {
<a name="l00351"></a>00351                         externalMarkedItem-&gt;unmarkPoint();
<a name="l00352"></a>00352                         externalMarkedPoint = -1;
<a name="l00353"></a>00353                 }
<a name="l00354"></a>00354 
<a name="l00355"></a>00355                 <span class="comment">// y si está sobre otro punto válido para el enlace, lo marco</span>
<a name="l00356"></a>00356                 Node *target = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(scene()-&gt;itemAt(event-&gt;scenePos())); <span class="comment">// en un futuro tendrá que hacer el cast a Node</span>
<a name="l00357"></a>00357                 <span class="keywordflow">if</span> (target)
<a name="l00358"></a>00358                 {
<a name="l00359"></a>00359                         <span class="comment">// obtengo el punto concreto a partir de las coordenadas locales al otro item</span>
<a name="l00360"></a>00360                         <span class="keywordtype">int</span> pointPos = target-&gt;pointAt(target-&gt;mapFromScene(event-&gt;scenePos()));
<a name="l00361"></a>00361                         <span class="keywordflow">if</span> (pointPos &gt;= 0)
<a name="l00362"></a>00362                         { <span class="comment">// marco el nuevo punto en función de la validez del enlace que generaría</span>
<a name="l00363"></a>00363                                 externalMarkedPoint = pointPos;
<a name="l00364"></a>00364                                 externalMarkedItem = target;
<a name="l00365"></a>00365                                 externalMarkedItem-&gt;markPoint(externalMarkedPoint, isValidLink(<span class="keyword">this</span>, clickedPoint, target, pointPos));
<a name="l00366"></a>00366                         }
<a name="l00367"></a>00367                 }
<a name="l00368"></a>00368         }
<a name="l00369"></a>00369 }
<a name="l00370"></a>00370 
<a name="l00371"></a>00371 <span class="keywordtype">void</span> Node::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
<a name="l00372"></a>00372 {
<a name="l00373"></a>00373         <span class="comment">// si no se ha arrastrado desde un punto hago un release normal</span>
<a name="l00374"></a>00374         <span class="keywordflow">if</span> (clickedPoint &lt; 0)
<a name="l00375"></a>00375         {
<a name="l00376"></a>00376                 QGraphicsItem::mouseReleaseEvent(event);
<a name="l00377"></a>00377         }
<a name="l00378"></a>00378         <span class="keywordflow">else</span>
<a name="l00379"></a>00379         {
<a name="l00380"></a>00380                 <span class="comment">// elimino la línea indicadora</span>
<a name="l00381"></a>00381                 <span class="keyword">delete</span>(line);
<a name="l00382"></a>00382 
<a name="l00383"></a>00383                 <span class="comment">// si había un punto marcado lo desmarco</span>
<a name="l00384"></a>00384                 <span class="keywordflow">if</span> (externalMarkedPoint &gt;= 0)
<a name="l00385"></a>00385                 {
<a name="l00386"></a>00386                         externalMarkedItem-&gt;unmarkPoint();
<a name="l00387"></a>00387                         externalMarkedPoint = -1;
<a name="l00388"></a>00388                 }
<a name="l00389"></a>00389 
<a name="l00390"></a>00390                 <span class="comment">// si está sobre un punto válido creo el enlace</span>
<a name="l00391"></a>00391                 Node *target = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(scene()-&gt;itemAt(event-&gt;scenePos())); <span class="comment">// en un futuro tendrá que hacer el cast a Node</span>
<a name="l00392"></a>00392                 <span class="keywordflow">if</span> (target)
<a name="l00393"></a>00393                 {
<a name="l00394"></a>00394                         <span class="comment">// obtiene el punto concreto a partir de las coordenadas locales al otro item</span>
<a name="l00395"></a>00395                         <span class="keywordtype">int</span> pointPos = target-&gt;pointAt(target-&gt;mapFromScene(event-&gt;scenePos()));
<a name="l00396"></a>00396 
<a name="l00397"></a>00397                         <span class="comment">// si es valido crea el enlace entre clickedPoint de this y pointPos de target</span>
<a name="l00398"></a>00398                         <span class="keywordflow">if</span> ( (pointPos &gt;= 0) &amp;&amp; isValidLink(<span class="keyword">this</span>, clickedPoint, target, pointPos) )
<a name="l00399"></a>00399                         {
<a name="l00400"></a>00400                                 <span class="keywordflow">if</span> (clickedPoint &gt;= numProp) <span class="comment">// si clickedPoint es un punto de salida, el enlace parte de this</span>
<a name="l00401"></a>00401                                         validLinkRelease(<span class="keyword">this</span>, clickedPoint, target, pointPos);
<a name="l00402"></a>00402                                 <span class="keywordflow">else</span> <span class="comment">// si no, parte de target</span>
<a name="l00403"></a>00403                                         validLinkRelease(target, pointPos, <span class="keyword">this</span>, clickedPoint);
<a name="l00404"></a>00404                         }
<a name="l00405"></a>00405                 }
<a name="l00406"></a>00406 
<a name="l00407"></a>00407                 clickedPoint = -1;
<a name="l00408"></a>00408         }
<a name="l00409"></a>00409 }
<a name="l00410"></a>00410 
<a name="l00411"></a>00411 <span class="keywordtype">void</span> Node::validLinkRelease(Node *fromNode, <span class="keywordtype">int</span> fromPoint, Node *toNode, <span class="keywordtype">int</span> toPoint)
<a name="l00412"></a>00412 {
<a name="l00413"></a>00413         window-&gt;createLink(fromNode, fromPoint, toNode, toPoint);
<a name="l00414"></a>00414 }
<a name="l00415"></a>00415 
<a name="l00416"></a>00416 <span class="keywordtype">void</span> Node::markPoint(<span class="keywordtype">int</span> point, <span class="keywordtype">bool</span> validity)
<a name="l00417"></a>00417 {
<a name="l00418"></a>00418         markedPoint = point;
<a name="l00419"></a>00419         markedValidity = validity;
<a name="l00420"></a>00420         update();
<a name="l00421"></a>00421 }
<a name="l00422"></a>00422 
<a name="l00423"></a>00423 <span class="keywordtype">void</span> Node::unmarkPoint()
<a name="l00424"></a>00424 {
<a name="l00425"></a>00425         markedPoint = -1;
<a name="l00426"></a>00426         update();
<a name="l00427"></a>00427 }
<a name="l00428"></a>00428 
<a name="l00429"></a>00429 <span class="comment">// indica si un enlace sería válido</span>
<a name="l00431"></a>00431 <span class="comment"></span><span class="keywordtype">bool</span> Node::isValidLink(Node *fromNode, <span class="keywordtype">int</span> fromPoint, Node *toNode, <span class="keywordtype">int</span> toPoint)<span class="keyword"> const</span>
<a name="l00432"></a>00432 <span class="keyword"></span>{
<a name="l00433"></a>00433         <span class="keywordtype">int</span> fromNumProp = fromNode-&gt;numProp;
<a name="l00434"></a>00434         <span class="keywordtype">int</span> toNumProp = toNode-&gt;numProp;
<a name="l00435"></a>00435 
<a name="l00436"></a>00436         <span class="keywordflow">if</span> (fromNode == toNode) <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// si son iguales</span>
<a name="l00437"></a>00437         <span class="keywordflow">if</span> (fromNode-&gt;parentItem() != toNode-&gt;parentItem()) <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// si no están al mismo nivel</span>
<a name="l00438"></a>00438         <span class="keywordflow">if</span> ( (fromPoint &lt; 0) || (toPoint &lt; 0) ) <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// si alguno no es un punto</span>
<a name="l00439"></a>00439         <span class="keywordflow">if</span> ( (fromPoint &lt; fromNumProp) &amp;&amp; (toPoint &lt; toNumProp) ) <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// si los dos son de entrada</span>
<a name="l00440"></a>00440         <span class="keywordflow">if</span> ( (fromPoint &gt;= fromNumProp) &amp;&amp; (toPoint &gt;= toNumProp) ) <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// si los dos son de salida</span>
<a name="l00441"></a>00441         <span class="keywordflow">if</span> ( (fromPoint &gt;= 2 * fromNumProp) || (toPoint &gt;= 2 * toNumProp) ) <span class="keywordflow">return</span> <span class="keyword">false</span>; <span class="comment">// si alguno no es un punto existente</span>
<a name="l00442"></a>00442         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00443"></a>00443 }
<a name="l00444"></a>00444 
<a name="l00445"></a>00445 <span class="keywordtype">int</span> Node::insertPos()<span class="keyword"> const</span>
<a name="l00446"></a>00446 <span class="keyword"></span>{
<a name="l00447"></a>00447         <span class="keywordflow">return</span> numProp;
<a name="l00448"></a>00448 }
<a name="l00449"></a>00449 
<a name="l00450"></a>00450 <span class="keywordtype">int</span> Node::insertProperty(QString name, <span class="keywordtype">int</span> type, <span class="keywordtype">bool</span> input, <span class="keywordtype">bool</span> output)
<a name="l00451"></a>00451 {
<a name="l00452"></a>00452         <span class="keywordtype">int</span> pos = insertPos();
<a name="l00453"></a>00453         insertProperty(pos, name, type, input, output);
<a name="l00454"></a>00454         <span class="keywordflow">return</span> pos;
<a name="l00455"></a>00455 }
<a name="l00456"></a>00456 
<a name="l00457"></a>00457 <span class="keywordtype">void</span> Node::insertProperty(<span class="keywordtype">int</span> pos, QString name, <span class="keywordtype">int</span> type, <span class="keywordtype">bool</span> input, <span class="keywordtype">bool</span> output)
<a name="l00458"></a>00458 {
<a name="l00459"></a>00459         prepareGeometryChange();
<a name="l00460"></a>00460         itemProp.insertProperty(pos, name, type, input, output);
<a name="l00461"></a>00461         numProp = itemProp.getProperties().size();
<a name="l00462"></a>00462 
<a name="l00463"></a>00463         CorrectTextChange();
<a name="l00464"></a>00464         update();
<a name="l00465"></a>00465 }
<a name="l00466"></a>00466 
<a name="l00467"></a>00467 <span class="keywordtype">void</span> Node::removeProperty(QString name)
<a name="l00468"></a>00468 {
<a name="l00469"></a>00469         prepareGeometryChange();
<a name="l00470"></a>00470         itemProp.deleteProperty(name);
<a name="l00471"></a>00471         numProp = itemProp.getProperties().size();
<a name="l00472"></a>00472 
<a name="l00473"></a>00473         CorrectTextChange();
<a name="l00474"></a>00474         update();
<a name="l00475"></a>00475 }
<a name="l00476"></a>00476 
<a name="l00477"></a>00477 <span class="keywordtype">void</span> Node::deleteProperty(<span class="keywordtype">int</span> pos)
<a name="l00478"></a>00478 {
<a name="l00479"></a>00479         prepareGeometryChange();
<a name="l00480"></a>00480         itemProp.deleteProperty(pos);
<a name="l00481"></a>00481         numProp = itemProp.getProperties().size();
<a name="l00482"></a>00482 
<a name="l00483"></a>00483         CorrectTextChange();
<a name="l00484"></a>00484         update();
<a name="l00485"></a>00485 }
<a name="l00486"></a>00486 
<a name="l00487"></a>00487 <span class="keywordtype">void</span> Node::CorrectTextChange()
<a name="l00488"></a>00488 {
<a name="l00489"></a>00489         <span class="comment">// recalcula el rectángulo exterior</span>
<a name="l00490"></a>00490     QFontMetricsF metrics = qApp-&gt;font();
<a name="l00491"></a>00491         lineSpacing = metrics.lineSpacing();
<a name="l00492"></a>00492     outlinerect = metrics.boundingRect(QString(<span class="stringliteral">&quot;&quot;</span>) + QString(<span class="stringliteral">&quot;(%1) &quot;</span>).arg(getId()) + name);
<a name="l00493"></a>00493 
<a name="l00494"></a>00494         <span class="keyword">const</span> QList&lt;QString&gt; props = itemProp.getProperties();
<a name="l00495"></a>00495         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; props.size(); i++)
<a name="l00496"></a>00496                 outlinerect |= metrics.boundingRect(props[i]);
<a name="l00497"></a>00497 
<a name="l00498"></a>00498     outlinerect.adjust(0.0, 0.0, lineSpacing*4, props.size()*metrics.lineSpacing() <span class="comment">/* sin +1, por que ya tiene el alto de una linea */</span>);
<a name="l00499"></a>00499 
<a name="l00500"></a>00500 
<a name="l00501"></a>00501         <span class="comment">// recalcula el texto a escribir</span>
<a name="l00502"></a>00502         QString propsText(<span class="stringliteral">&quot;&quot;</span>);
<a name="l00503"></a>00503         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; props.size(); i++) {
<a name="l00504"></a>00504                 <span class="keywordflow">if</span> (i &gt; 0) propsText += QString(<span class="stringliteral">&quot;\n&quot;</span>);
<a name="l00505"></a>00505                 propsText += props[i];
<a name="l00506"></a>00506         }
<a name="l00507"></a>00507 
<a name="l00508"></a>00508         setText(propsText);
<a name="l00509"></a>00509         updateLinksPos();
<a name="l00510"></a>00510 }
<a name="l00511"></a>00511 
<a name="l00512"></a>00512 <span class="keywordtype">void</span> Node::delLastProp()
<a name="l00513"></a>00513 {
<a name="l00514"></a>00514         prepareGeometryChange();
<a name="l00515"></a>00515         deleteProperty(numProp - 2);
<a name="l00516"></a>00516         update();
<a name="l00517"></a>00517 }
<a name="l00518"></a>00518 
<a name="l00519"></a>00519 QVariant Node::itemChange(GraphicsItemChange change,
<a name="l00520"></a>00520                           <span class="keyword">const</span> QVariant &amp;value)
<a name="l00521"></a>00521 {
<a name="l00522"></a>00522     <span class="keywordflow">if</span> (change == ItemPositionHasChanged)
<a name="l00523"></a>00523                 updateLinksPos();
<a name="l00524"></a>00524 
<a name="l00525"></a>00525     <span class="keywordflow">return</span> QGraphicsItem::itemChange(change, value);
<a name="l00526"></a>00526 }
<a name="l00527"></a>00527 
<a name="l00528"></a>00528 <span class="keywordtype">void</span> Node::updateLinksPos()
<a name="l00529"></a>00529 {
<a name="l00530"></a>00530         <span class="keywordflow">foreach</span> (Link *link, getLinks())
<a name="l00531"></a>00531                 link-&gt;trackNodes();
<a name="l00532"></a>00532 }
<a name="l00533"></a>00533 
<a name="l00534"></a>00534 QRectF Node::outlineRect()<span class="keyword"> const</span>
<a name="l00535"></a>00535 <span class="keyword"></span>{
<a name="l00536"></a>00536         <span class="keywordflow">return</span> outlinerect;
<a name="l00537"></a>00537 }
<a name="l00538"></a>00538 
<a name="l00539"></a>00539 <span class="keywordtype">int</span> Node::roundness(<span class="keywordtype">double</span> size)<span class="keyword"> const</span>
<a name="l00540"></a>00540 <span class="keyword"></span>{
<a name="l00541"></a>00541     <span class="keyword">const</span> <span class="keywordtype">int</span> Diameter = 12;
<a name="l00542"></a>00542     <span class="keywordflow">return</span> 100 * Diameter / int(size);
<a name="l00543"></a>00543 }
<a name="l00544"></a>00544 
<a name="l00545"></a>00545 <span class="comment">// Devuelve el indice del punto de enlace que hay debajo de la posición &quot;pos&quot;, en coordenadas del blocknode;</span>
<a name="l00546"></a>00546 <span class="comment">// empieza a contar desde 0 y los de los de salida los cuenta a continuación de los de entrada;</span>
<a name="l00547"></a>00547 <span class="comment">// si &quot;pos&quot; no está sobre ningún punto de enlace válido devuelve -1.</span>
<a name="l00548"></a>00548 <span class="keywordtype">int</span> Node::pointAt(QPointF pos)<span class="keyword"> const</span>
<a name="l00549"></a>00549 <span class="keyword"></span>{
<a name="l00550"></a>00550         QRectF rect = outlineRect();
<a name="l00551"></a>00551         <span class="keywordflow">if</span> ((pos.x() &gt;= rect.left() + lineSpacing*0.1) &amp;&amp; (pos.x() &lt;= rect.left() + lineSpacing*0.9)) <span class="comment">// si está en la columna de entrada</span>
<a name="l00552"></a>00552         {
<a name="l00553"></a>00553                 <span class="keywordflow">if</span> (pos.y() - rect.top() &gt;= lineSpacing*1.1) <span class="comment">// si está por debajo del título</span>
<a name="l00554"></a>00554                 {
<a name="l00555"></a>00555                         <span class="keywordtype">int</span> relativePos = (int)(pos.y() - rect.top() - lineSpacing*1.1);
<a name="l00556"></a>00556                         <span class="keywordflow">if</span> (relativePos % (<span class="keywordtype">int</span>)lineSpacing &lt;= lineSpacing*0.8) <span class="comment">// si está sobre el lugar del punto</span>
<a name="l00557"></a>00557                                 <span class="keywordflow">if</span> (itemProp.isInput((<span class="keywordtype">int</span>)(relativePos / lineSpacing))) <span class="keywordflow">return</span> (<span class="keywordtype">int</span>)(relativePos / lineSpacing); <span class="comment">// si la propiedad tiene enlace de entrada, es valido</span>
<a name="l00558"></a>00558                 }
<a name="l00559"></a>00559         }
<a name="l00560"></a>00560         <span class="keywordflow">else</span> <span class="keywordflow">if</span> ((pos.x() &gt;= rect.right() - lineSpacing*0.9) &amp;&amp; (pos.x() &lt;= rect.right() - lineSpacing*0.1)) <span class="comment">// si está en la columna de salida</span>
<a name="l00561"></a>00561         {
<a name="l00562"></a>00562                 <span class="keywordflow">if</span> (pos.y() - rect.top() &gt;= lineSpacing*1.1) <span class="comment">// si está por debajo del título</span>
<a name="l00563"></a>00563                 {
<a name="l00564"></a>00564                         <span class="keywordtype">int</span> relativePos = (int)(pos.y() - rect.top() - lineSpacing*1.1);
<a name="l00565"></a>00565                         <span class="keywordflow">if</span> (relativePos % (<span class="keywordtype">int</span>)lineSpacing &lt;= lineSpacing*0.8) <span class="comment">// si está sobre el lugar del punto</span>
<a name="l00566"></a>00566                                 <span class="keywordflow">if</span> (itemProp.isOutput((<span class="keywordtype">int</span>)(relativePos / lineSpacing))) <span class="keywordflow">return</span> (<span class="keywordtype">int</span>)(relativePos / lineSpacing + numProp);  <span class="comment">// si la propiedad tiene enlace de salida, es valido</span>
<a name="l00567"></a>00567                 }
<a name="l00568"></a>00568         }
<a name="l00569"></a>00569         <span class="keywordflow">return</span> -1;
<a name="l00570"></a>00570 }
<a name="l00571"></a>00571 
<a name="l00572"></a>00572 QString Node::propName(<span class="keywordtype">int</span> point)<span class="keyword"> const</span>
<a name="l00573"></a>00573 <span class="keyword"></span>{
<a name="l00574"></a>00574         <span class="keywordflow">if</span> ( (point &lt; 0) || (point &gt;= 2 * numProp) ) <span class="keywordflow">return</span> QString(); <span class="comment">// si point se sale de rango</span>
<a name="l00575"></a>00575 
<a name="l00576"></a>00576         <span class="keywordflow">if</span> (point &gt;= numProp) point = point - numProp; <span class="comment">// ignoro si es de entrada o salida</span>
<a name="l00577"></a>00577         <span class="keywordflow">return</span> itemProp.getProperties()[point];
<a name="l00578"></a>00578 }
<a name="l00579"></a>00579 
<a name="l00580"></a>00580 <span class="keywordtype">int</span> Node::propPoint(QString name, <span class="keywordtype">bool</span> in)<span class="keyword"> const</span>
<a name="l00581"></a>00581 <span class="keyword"></span>{
<a name="l00582"></a>00582         <span class="keywordtype">int</span> pos = itemProp.getProperties().indexOf(name);
<a name="l00583"></a>00583         <span class="keywordflow">if</span> (pos &lt; 0) <span class="keywordflow">return</span> pos;
<a name="l00584"></a>00584         <span class="keywordflow">if</span> (!in) <span class="keywordflow">return</span> pos += numProp;
<a name="l00585"></a>00585         <span class="keywordflow">return</span> pos;
<a name="l00586"></a>00586 }
<a name="l00587"></a>00587 
<a name="l00588"></a>00588 <span class="keywordtype">int</span> Node::propType(<span class="keywordtype">int</span> point)<span class="keyword"> const</span>
<a name="l00589"></a>00589 <span class="keyword"></span>{
<a name="l00590"></a>00590         <span class="keywordflow">if</span> ( (point &lt; 0) &amp;&amp; (point &gt;= 2 * numProp) ) <span class="keywordflow">return</span> 0; <span class="comment">// si point se sale de rango devuelvo &quot;no type&quot;</span>
<a name="l00591"></a>00591 
<a name="l00592"></a>00592         <span class="keywordflow">if</span> (point &gt;= numProp) point = point - numProp; <span class="comment">// ignoro si es de entrada o salida</span>
<a name="l00593"></a>00593         <span class="keywordflow">return</span> itemProp.propertyType(point);
<a name="l00594"></a>00594 }
<a name="l00595"></a>00595 
<a name="l00596"></a>00596 <span class="keywordtype">void</span> Node::setHide(<span class="keywordtype">bool</span> hide)
<a name="l00597"></a>00597 {
<a name="l00598"></a>00598         <span class="keywordflow">foreach</span>(Link *link, getLinks())
<a name="l00599"></a>00599                 link-&gt;setVisible(!hide);
<a name="l00600"></a>00600 
<a name="l00601"></a>00601         setVisible(!hide);
<a name="l00602"></a>00602 }
<a name="l00603"></a>00603 
</pre></div></div>
</td></tr></table>

<br /><hr><br />
<center><a href="http://perception.inf.um.es/QVision">QVision framework</a>.
<a href="http://perception.inf.um.es">PARP research group</a>.
Copyright &copy; 2007, 2008, 2009, 2010, 2011.</center>
<br />
</body>
</html>
